        TITL DAI FIRMWARE 0E016-0E1F4  V1.1
        ORG   :E016
*
*
*
**************************
* RUN basiccmd WAIT TIME *
**************************
*
* Timer 01BE/BF is decremented by clock
* interrupt RST7.
*
RWTET   CALL  :E6F8     Get time to wait
        SHLD  :01BE     Load timer
RWT40   LHLD  :01BE     Get timer
        MOV   A,H
        ORA   L
        RZ              Abort if (timer)=0
        CALL  :D6A5     Check keyb for new inputs
        JNC   :E01C     Again if no break pressed
 REM
* If suspended:
 REM
        JMP   :E012     Abort, 'command broken in'
*
***************************************
* RUN basiccmd FOR .. TO .. (STEP ..) *
***************************************
*
RFOR    POP   D         Kill return addr
        CALL  :E13C     Save old FRAME on stack
        CALL  :E45A     Init variable
        SHLD  :0104     Remember location variable
        ANI   :30
        SUI   :10       Set flags for var.type
        CALL  :E808     Eval TO expr, result in MACC
        JZ    :E0A2     If INT variable
 REM
* If FPT variable:
 REM
        RST   4         Subtract 'FROM'
        DATA  :03
        LXI   H,:0106   Get addr. LSTPF
        MVI   M,:00     Default STEP implicit
        LDAX  B         Get evt. STEP val. from text
        INX   B
        CPI   :FF
        JZ    :E05F     Jump if no STEP
 REM
* If STEP:
 REM
        CALL  :C018     Save 'to-from' on stack
        INR   M         Stepflag explicit
        DCX   B
        CALL  :E808     Stepvalue in MACC
        LXI   H,:0107   Addr. LSTEP
        RST   4         Stepvalue in LSTEP
        DATA  :0F
        CALL  :C01B     'to-from' range in MACC
        RST   4         Find nr of iterations
        DATA  :09
RFR10   RST   4         Make it INT
        DATA  :48
RFR20   LXI   H,:010B   Addr. LCOUNT
        RST   4         Iterations in LCOUNT
        DATA  :0F
        MOV   A,M
        ORA   A
        CM    :CB9E     Clear LCOUNT if loop in
 REM wrong direction
        MOV   H,B       ) Current pos in start of
        MOV   L,C       ) loop in HL
        SHLD  :010F     Set pointer to start loop
 REM
* Now delete any previous use of the loop:
 REM
        LXI   B,:0010   Size of 1 'FOR' stackframe
        LHLD  :0104     Get current loop variable
        XCHG            in DE
        LXI   H,:0000
        DAD   SP        Stack start
        JMP   :E07F     Into loop
 REM
* Loop:
 REM
RFR30   DAD   B         Up 1 frame
RFR40   MOV   A,M
        INX   H
        ORA   M
        JZ    :E09F     Jump if top of stack
        MOV   A,M
        DCX   H
        CMP   D         Comp top byte variable addr
        JNZ   :E07E     Again if not the same
        MOV   A,M
        SUB   E
        JNZ   :E07E     Cont if bottombyte different
        PUSH  H         Frame bottom to be removed
        LXI   H,:0002
        DAD   SP        Update stackpointer
        MOV   D,H       ) DE is bottom of area to be
        MOV   E,L       ) moved
        DAD   B         Add 1 frame
        MOV   B,H       ) Place to move area to
        MOV   C,L       )
        POP   H         Top area to move
        CALL  :DE4F     Remove old frame
        SPHL            New stack position
RFR50   JMP   :E114     Use common mode to re-
 REM instate textpointer
 REM
* If INT variable:
 REM
RFR70   RST   4         Subtract 'from'
        DATA  :51
        LXI   H,:0106   Get addr. LSTPF
        MVI   M,:80     Default step implicit
        LDAX  B         Get evt STEP value
        INX   B
        CPI   :FF
        JZ    :E061     If no step given
 REM
* If STEP:
 REM
        CALL  :C018     Save 'to-from' on stack
        INR   M         Stepflag explicit
        DCX   B
        CALL  :E808     Get stepvalue in MACC
        LXI   H,:0107   Addr. stepvalue if explicit
        RST   4         Stepvalue in LSTEP
        DATA  :0F
        CALL  :C01B     'to-from' range in MACC
        RST   4         Find nr of iterations
        DATA  :57
        JMP   :E061     Handle loop
*
**************************************
* RUN basiccmd NEXT <named variable> *
**************************************
*
RNEXI   POP   D         Returnaddr
        CALL  :E963     Get varptr in HL
RNX10   XCHG
        LHLD  :0104     Get current loop variable
        MOV   A,L
        ORA   H         Loopvariable 0?
        JZ    :DA2E     Then run error 'NEXT
 REM WITHOUT FOR'
        CALL  :DE14     Compare loop and named
 REM variable pntrs
        JZ    :E0EE     Perform NEXT if identical
        XCHG
        SHLD  :0119     Store in scratch area
        CALL  :E167     Re-instate next loopvariable
        LHLD  :0119     Get it back
        JMP   :E0C9     Try for a match
*
*********************
* RUN basiccmd NEXT *
*********************
*
* No variable name is given.
*
RNEXT   POP   D         Returnaddr
        LHLD  :0104     Get current loop variable
        MOV   A,L
        ORA   H         Loopvar is 0?
        JZ    :DA2E     Then run error 'NEXT
 REM WITHOUT FOR'
RNX20   LDA   :0106     Get LSTPF
        ORA   A
        JM    :E133     Jump if INT loop variable
 REM
* If FPT loop variable:
 REM
        RAR
        JC    :E11D     Jump if explicit step
        CALL  :C006     Incr. variable in memory
RNX30   LXI   H,:010E   Addr lobyte LCOUNT
RNX40   MOV   A,M       Get lobyte
        SUI   :01
        MOV   M,A       Decr it
        JNC   :E114     Continu if no overflow
        DCX   H         Pnts to next byte LCOUNT
        MOV   A,L
        CPI   :0A       Hibyte done?
        JNZ   :E0FF     More bytes if not
 REM
* Loop finished:
 REM
        CALL  :E167     Pop frame
        ORA   A         No special action
        JMP   :C88F     Exit to Basic monitor
 REM
* More time round (entry from 'FOR'):
 REM
RNX50   LHLD  :010F     Get pntr to start loop
        MOV   B,H       ) in BC
        MOV   C,L       )
        ORA   A         No special action
        JMP   :C88F     Exit to Basic monitor
 REM
* Explicit step:
 REM
RNX60   RST   4         Get value loopvar in MACC
        DATA  :0C
        PUSH  H
        LXI   H,:0107   Addr. LSTEP
        JNC   :E128     If INT
        RST   4         FPT: add stepvalue
        DATA  :00
L0E19   JC    :E12D     If FPT
        RST   4         INT: add stepvalue
        DATA  :4E
L0E20   POP   H
        RST   4         Store new value in
        DATA  :0F       variable
        JMP   :E0FC     Test end of loop
 REM
* If INT loopvariable:
 REM
RNX70   JPE   :E11D     Jump if explicit step
        CALL  :C00F     Incr. variable in memory
        JMP   :E0FC     Test end of loop
*
**************
* PUSH FRAME *
**************
*
* Several pointers are save on stack during
* execution of FOR-NEXT loops.
*
PUSHF   POP   D         Get addr. where to continue
        LHLD  :0104     Get current loop variable
        MOV   A,H
        ORA   L         Check if 0
        JZ    :E164     Then abort routine
        LHLD  :010F
        PUSH  H         Save pntr to start loop
        LHLD  :0111
        PUSH  H         Save pntr to start loop line
        LHLD  :010B
        PUSH  H         ) Save loop iteration count
        LHLD  :010D     ) (4 bytes)
        PUSH  H
        LHLD  :0107
        PUSH  H         ) Save step value
        LHLD  :0109     ) (4 bytes)
        PUSH  H
        LDA   :0106
        PUSH  PSW       Save LSTPF
        LHLD  :0104
PU1     PUSH  H         Save current loop variable
        XCHG            Addr. to continue in HL
        PCHL            Set program counter
*
*************
* POP FRAME *
*************
*
* Restores looppointers in RAM.
*
POPF    POP   D
        POP   H
        SHLD  :0104     Restore LOPVAR
        MOV   A,H
        ORA   L         LOPVAR=0?
        JZ    :E18D     Then abort routine
        POP   PSW
        STA   :0106     Restore LSTPF
        POP   H         )
        SHLD  :0109     ) Restore LSTEP
        POP   H         ) (4 bytes)
        SHLD  :0107     
        POP   H         )
        SHLD  :010D     ) Restore LCOUNT
        POP   H         ) (4 bytes)
        SHLD  :010B     
        POP   H
        SHLD  :0111     Restore LOPLN
        POP   H
        SHLD  :010F     Restore LOPPT
PP1     PUSH  D
        RET
*
**********************************
* RUN basiccmds DATA - REM - IMP *
**********************************
*
* RREM/RDATA:
*    Entry: B: Points to length byte of string.
*    Exit:  DEHL preserved. AF corrupted.
* RIMP:
*    No action.
*
*RREM
RDATA   LDAX  B         Get length of string
 REM
* Entry for REXPS:
 REM
RRM10   INX   B         BC points to 1st char
        ADD   C
        MOV   C,A       BC points to end of string
        RNC      
        INR   B         If overflow: correct B
 REM
* Entry for RUN IMP:
 REM
RIMP    ORA   A         No special action
        RET
 REM
*********************
* RUN basiccmd LIST *
*********************
*
* The whole textbuffer contents is listed.
*
*RLIST
RLIS0   MVI   A,:FF     Init. mode 0
        RST   5         Change mode
        DATA  :18
        MVI   A,:0C
        RST   5         Clear screen
        DATA  :03
RLS05   LHLD  :029F     Get startaddr. textbuf
        XCHG            in DE
        LHLD  :02A1     Get start symtab
        DCX   H         End textbuf in HL
        JMP   :E1CF     Perform listing
*
**********************************
* RUN basiccmd LIST <linenumber> *
**********************************
*
* Entry: BC points to linenumber.
* Exit:  BC updated. AFDEHL corrupted.
*
RLIS1   CALL  :E6E7     Read linenr and find
 REM it in textbuf
        NOP
        MOV   D,H       ) Linenr in DE
        MOV   E,L       )
        CC    :DE39     If linenr found: calc addr
 REM after string in HL
        JMP   :E1CF     Perform listing
*
*****************************
* RUN basiccmd LIST <range> *
*****************************
*
* Entry: BC points to 1st linenumber.
* Exit:  BC updated. AFDEHL corrupted.
*
RLIS2   LHLD  :029F     Get start textbuf
        CALL  :E6D9     Read 1st linenr
        CNZ   :CAF6     If given: Find it in textbuf
        XCHG            Addr in DE
        LHLD  :02A1     Get start symtab
        DCX   H         End textbuf in HL
        CALL  :E6D9     Read 1st linenr
        STC
        CMC
        CNZ   :CAF6     If 1st nr found: find 2nd
        CC    :DE39     If found: Calc addr after
 REM string in HL
 REM
* Perform listing:
 REM
RLS10   PUSH  B
        MOV   B,D       ) Start listed area in BC
        MOV   C,E       )
        SHLD  :011B     Store end listed area
        XCHG            also in DE
        SHLD  :0119     Store start listed area
RLS20   MOV   H,B       ) Startaddr in HL
        MOV   L,C       )
        CALL  :DE14     Check if all lines listed
        JZ    :E1F2     Abort if ready
        CALL  :D873     List curent line if linenr
 REM correct
        CALL  :D6BB     Scan keyboard
        JC    :E1F2     Break pressed: stop listing
        NOP
        NOP
        CNZ   :D6DA     If a key is pressed:
 REM Wait for spacebar
        JNC   :E1D9     No break: list further
 REM
* If ready:
 REM
RLS30   ORA   A         No special action
        POP   B
        RET
*
*
*
        UNL
RLIST   EQU RLIS0
RREM    EQU RDATA
        LST
        END
